﻿using System;
using System.Net;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;
using Net.Event;
using Net.Share;

namespace Net.System
{
    /// <summary>
    /// 线程管线(流水线) --单线程版
    /// </summary>
    /// <typeparam name="Worker"></typeparam>
    public class ThreadPipelineOne<Worker> : IThreadPipeline
    {
        /// <summary>
        /// 并发线程数量, 发送线程和接收处理线程数量
        /// </summary>
        public int MaxThread { get; set; } = Environment.ProcessorCount * 2;
        /// <summary>
        /// 是否工作中?
        /// </summary>
        public bool IsWorking { get; private set; }
        /// <summary>
        /// 线程组, 优化多线程资源竞争问题
        /// </summary>
        public List<ThreadGroup<Worker>> Groups { get; private set; } = new();
        public int GroupCount => Groups.Count;

        /// <summary>
        /// 当线程组处理
        /// </summary>
        public Action<ThreadGroup<Worker>> OnProcess;

        private int threadCount;

        /// <summary>
        /// 初始化线程管线
        /// </summary>
        /// <param name="name"></param>
        public void Init(string name)
        {
            for (int i = 0; i < MaxThread; i++)
            {
                var group = new ThreadGroup<Worker>()
                {
                    Id = i + 1
                };
                Groups.Add(group);
            }
        }

        /// <summary>
        /// 开始线程管线
        /// </summary>
        public void Start()
        {
            IsWorking = true;
        }

        /// <summary>
        /// 选择线程群
        /// </summary>
        /// <returns></returns>
        public ThreadGroup<Worker> SelectGroup()
        {
            var value = threadCount++;
            return Groups[value % Groups.Count];
        }

        /// <summary>
        /// 添加工作者
        /// </summary>
        /// <param name="worker"></param>
        public void AddWorker(Worker worker)
        {
            SelectGroup().Add(worker);
        }

        /// <summary>
        /// 移除工作者
        /// </summary>
        /// <param name="worker"></param>
        public void RemoveWorker(Worker worker)
        {
            for (int i = 0; i < Groups.Count; i++) //只能一个一个寻找移除
            {
                Groups[i].Remove(worker);
            }
        }

        public void Update()
        {
            for (int i = 0; i < Groups.Count; i++)
            {
                OnProcess(Groups[i]); //单线程处理
            }
        }

        public void Stop() => Dispose();

        public void Dispose()
        {
            IsWorking = false;
            Groups.Clear();
        }

        public void SetProcess<T>(Action<ThreadGroup<T>> processing)
        {
            OnProcess = processing as Action<ThreadGroup<Worker>>;
        }

        public void SetProcess<T1, T2>(Action<ThreadGroup<T1, T2>> processing)
        {
            throw new NotImplementedException();
        }

        public ThreadGroup GetGroup(int index)
        {
            return Groups[index];
        }

        ThreadGroup IThreadPipeline.SelectGroup()
        {
            return SelectGroup();
        }
    }
}